package com.winsdom.service.customer.impl;

import com.winsdom.entity.customer.CustomerIndividualCreateRequest;
import com.winsdom.mapper.customer.CustomerIndividualCreateMapper;
import com.winsdom.service.customer.CustomerIndividualCreateService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;
import java.util.LinkedHashSet;

/**
 * 个体工商户客户创建服务实现类
 * <p>
 * 负责处理个体工商户客户的完整创建流程，包括：
 * 1. 客户类型校验（强制为个体户）
 * 2. 客户主表及扩展表插入
 * 3. 经营地址、营业执照信息处理
 * 4. 联系人信息及楼盘分类关联管理
 * <p>
 * 所有操作通过@Transactional注解保证事务一致性，
 * 若中途出现异常将自动回滚，确保数据完整性。
 */
@Service
@Transactional
public class CustomerIndividualCreateServiceImpl implements CustomerIndividualCreateService {
    @Resource
    private CustomerIndividualCreateMapper mapper;

    /**
     * 创建个体工商户客户的完整业务流程
     * <p>
     * 执行顺序：
     * 1. 校验并设置客户类型为个体户（强制）
     * 2. 插入客户主表记录并获取自增ID
     * 3. 插入个体户扩展表信息
     * 4. 插入经营地址信息（非空时）
     * 5. 插入营业执照图片信息（非空时）
     * 6. 处理联系人及楼盘分类关联（支持多联系人、去重楼盘）
     *
     * @param request 个体工商户创建请求实体，包含完整的客户信息
     */
    @Override
    public void create(CustomerIndividualCreateRequest request) {
        // 1. 校验并强制设置客户类型为个体户（业务规则：个体工商户类型固定为2）
        validateCustomerType(request);

        // 2. 插入客户主表（存储基础客户信息）
        mapper.insertCustomer(request);
        // 获取数据库生成的自增客户ID（用于后续关联表插入）
        Long customerId = mapper.getLastInsertId();

        // 3. 插入个体户扩展表（存储个体工商户特有信息，如经营者姓名、身份证号等）
        request.setCustomerId(customerId);
        mapper.insertIndividualBusiness(request);

        // 4. 插入经营地址信息（请求中包含地址时执行）
        mapper.insertBusinessAddress(request);

        // 5. 插入营业执照图片信息（非空时执行）
        if (Objects.nonNull(request.getBusinessLicenseImage())) {
            mapper.insertBusinessLicense(request);
        }

        // 6. 处理联系人及楼盘分类关联（支持多联系人，自动去重楼盘名称）
        processContactsAndProperties(customerId, request);
    }

    /**
     * 校验并强制设置客户类型为个体户（类型编码2）
     * <p>
     * 业务规则：个体工商户创建时，客户类型必须为个体户，
     * 若请求中未指定或类型不符，自动修正为类型2。
     *
     * @param request 个体工商户创建请求实体
     */
    private void validateCustomerType(CustomerIndividualCreateRequest request) {
        // 个体工商户对应的类型编码为2（系统约定）
        if (request.getCustomerType() == null || !request.getCustomerType().equals(2)) {
            request.setCustomerType(2);
            // 记录日志或打印提示（示例中省略，实际开发中可添加日志）
            System.out.println("自动修正客户类型为个体工商户（类型ID：2）");
        }
    }

    /**
     * 处理联系人信息及联系人-楼盘分类关联关系
     * <p>
     * 逻辑说明：
     * 1. 遍历所有联系人，插入联系人基本信息
     * 2. 获取联系人ID后，对楼盘名称列表进行去重（避免重复关联）
     * 3. 根据去重后的楼盘名称查询分类ID，插入关联关系
     *
     * @param customerId 客户ID，关联客户主表
     * @param request    个体工商户创建请求实体，包含联系人信息
     */
    private void processContactsAndProperties(Long customerId, CustomerIndividualCreateRequest request) {
        if (request.getContactInfos() != null) {
            for (CustomerIndividualCreateRequest.ContactInfo contact : request.getContactInfos()) {
                // 插入联系人基本信息（关联客户ID）
                mapper.insertContact(customerId, contact);
                // 获取新插入的联系人ID（由数据库自增生成）
                Long contactId = contact.getContactId();

                // 对联系人关联的楼盘名称进行去重（保持顺序）
                Set<String> uniqueProperties = new LinkedHashSet<>(contact.getReceiveProperties());

                // 插入去重后的楼盘分类关联（避免重复数据）
                uniqueProperties.forEach(propertyName -> {
                    // 根据楼盘名称查询分类ID（可能为null，需判空）
                    Long categoryId = mapper.selectCategoryIdByName(propertyName);
                    if (categoryId != null) {
                        // 插入联系人与分类的关联关系
                        mapper.insertContactProperty(contactId, categoryId);
                        System.out.println("成功关联联系人ID " + contactId + " 与楼盘分类ID " + categoryId);
                    } else {
                        System.out.println("警告：未找到楼盘名称 [" + propertyName + "] 对应的分类ID，跳过关联");
                    }
                });
            }
        }
    }
}